package org.springframework.aop.framework.autoproxy;

import java.util.List;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

import com.demo.spring.aop底层演示.demo.Aspect1;
import com.demo.spring.aop底层演示.demo.Config;
import com.demo.spring.aop底层演示.demo.Target1;
import com.demo.spring.aop底层演示.demo.Target2;

// 其它见《com.demo.spring.aop底层演示.demo》
// Test类在org.springframework.aop.framework.autoproxy里，为了可以调用受保护的方法
public class Test {
	
	public static void main(String[] args) {
		GenericApplicationContext context = new GenericApplicationContext();
		context.registerBeanDefinition("aspect1", new AnnotatedGenericBeanDefinition(Aspect1.class));
		context.registerBeanDefinition("config", new AnnotatedGenericBeanDefinition(Config.class));
		context.registerBeanDefinition("configurationClassPostProcessor", new AnnotatedGenericBeanDefinition(ConfigurationClassPostProcessor.class));
		// 这里还是要初始化一下，不然会有空指针错误
		context.registerBeanDefinition("annotationAwareAspectJAutoProxyCreator", new AnnotatedGenericBeanDefinition(AnnotationAwareAspectJAutoProxyCreator.class));
		// 也不能把target1注册为spring的bean，因为这样这个bean本身就会被AnnotationAwareAspectJAutoProxyCreator代理，后面的测试代码会导致二次代理
		
		context.refresh();
		for(String name : context.getBeanDefinitionNames()) {
			System.out.println(name);
		}
		AnnotationAwareAspectJAutoProxyCreator creator = (AnnotationAwareAspectJAutoProxyCreator)context.getBean("annotationAwareAspectJAutoProxyCreator");
		List<Advisor> advisors = creator.findEligibleAdvisors(Target1.class, "target1");
		for (Advisor advisor : advisors) {
			System.out.println(advisor);
		}
		Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1");
		((Target1)o1).foo();
	}

}
